package org.elasticsearch.plugin.analysis.ik;

import org.elasticsearch.action.*;
import org.elasticsearch.client.ElasticsearchClient;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;

import java.io.IOException;

import static org.elasticsearch.action.ValidateActions.addValidationError;

public class CreateModelFromSetAction extends Action<CreateModelFromSetAction.CreateModelFromSetRequest,
        CreateModelFromSetAction.CreateModelFromSetResponse, CreateModelFromSetAction.CreateModelFromSetRequestBuilder> {
    public static final String NAME = "cluster:admin/ltr/store/create-model-from-set";
    public static final CreateModelFromSetAction INSTANCE = new CreateModelFromSetAction();

    protected CreateModelFromSetAction() {
        super(NAME);
    }

    @Override
    public CreateModelFromSetRequestBuilder newRequestBuilder(ElasticsearchClient client) {
        return new CreateModelFromSetRequestBuilder(client);
    }

    /**
     * Creates a new response instance.
     */
    @Override
    public CreateModelFromSetResponse newResponse() {
        return new CreateModelFromSetResponse();
    }

    public static class CreateModelFromSetRequestBuilder extends ActionRequestBuilder<CreateModelFromSetRequest,
            CreateModelFromSetResponse, CreateModelFromSetRequestBuilder> {

        protected CreateModelFromSetRequestBuilder(ElasticsearchClient client) {
            super(client, INSTANCE, new CreateModelFromSetRequest());
        }

        public CreateModelFromSetRequestBuilder withVersion(String store, String featureSetName, long expectedSetVersion, String modelName) {
            request.store = store;
            request.featureSetName = featureSetName;
            request.expectedSetVersion = expectedSetVersion;
            request.modelName = modelName;
            return this;
        }

        public CreateModelFromSetRequestBuilder withoutVersion(String store, String featureSetName, String modelName) {
            request.store = store;
            request.featureSetName = featureSetName;
            request.expectedSetVersion = null;
            request.modelName = modelName;
            return this;
        }

        public CreateModelFromSetRequestBuilder routing(String routing) {
            request.setRouting(routing);
            return this;
        }
    }

    public static class CreateModelFromSetRequest extends ActionRequest {
        private String store;
        private String featureSetName;
        private Long expectedSetVersion;
        private String modelName;
        private String routing;

        public CreateModelFromSetRequest() {
        }

        @Override
        public ActionRequestValidationException validate() {
            ActionRequestValidationException arve = null;
            if (store == null) {
                arve = addValidationError("store must be set", null);
            }
            if (featureSetName == null) {
                arve = addValidationError("featureSetName must be set", arve);
            }
            if (modelName == null) {
                arve = addValidationError("modelName must be set", arve);
            }
            return arve;
        }

        @Override
        public void readFrom(StreamInput in) throws IOException {
            super.readFrom(in);
            store = in.readString();
            featureSetName = in.readString();
            expectedSetVersion = in.readOptionalLong();
            modelName = in.readString();
            routing = in.readOptionalString();
        }

        @Override
        public void writeTo(StreamOutput out) throws IOException {
            super.writeTo(out);
            out.writeString(store);
            out.writeString(featureSetName);
            out.writeOptionalLong(expectedSetVersion);
            out.writeString(modelName);
            out.writeOptionalString(routing);
        }

        public String getStore() {
            return store;
        }

        public String getFeatureSetName() {
            return featureSetName;
        }

        public String getModelName() {
            return modelName;
        }

        public Long getExpectedSetVersion() {
            return expectedSetVersion;
        }

        public String getRouting() {
            return routing;
        }

        public void setRouting(String routing) {
            this.routing = routing;
        }
    }

    public static class CreateModelFromSetResponse extends ActionResponse implements ToXContentObject {
        private static final int VERSION = 1;
        private String response;

        public CreateModelFromSetResponse() {
        }

        public CreateModelFromSetResponse(String response) {
            this.response = response;
        }

        @Override
        public void readFrom(StreamInput in) throws IOException {
            super.readFrom(in);
            int version = in.readVInt();
            assert version == VERSION;
            response = in.readString();
        }

        @Override
        public void writeTo(StreamOutput out) throws IOException {
            super.writeTo(out);
            out.writeVInt(VERSION);
            out.writeString(response);
        }

        @Override
        public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
            return builder.startObject()
                    .field("yes", response)
                    .endObject();
        }
    }
}